#include "ArbGeomNode.h"

ArbGeomNode::ArbGeomNode(void)
{
	iNumVerts = 0;
	iNumIndex = 0;
	SetMaterial(1.0f, 1.0f, 1.0f);
	pGeomMesh = NULL;
	pVerts = new CUSTOMVERTEX[iNumVerts];
	iIndicies = new short[iNumIndex];
}


ArbGeomNode::ArbGeomNode(Vertex* pVertsIn, int nV, short* pIndex, int nI)
{
	iNumVerts = nV;
	iNumIndex = nI;
	SetMaterial(1.0f, 1.0f, 1.0f);
	pGeomMesh = NULL;
	pVerts = new CUSTOMVERTEX[iNumVerts];
	iIndicies = new short[iNumIndex];
	for(int i = 0; i < iNumVerts; i++)
	{
		pVerts[i].position = pVertsIn[i].GetPos();
		pVerts[i].normal = pVertsIn[i].GetNorm();
	}
	for(int i = 0; i < iNumIndex; i++)
	{
		iIndicies[i] = pIndex[i];
	}
}
ArbGeomNode::ArbGeomNode(const ArbGeomNode& rhs)
{
	iNumVerts = rhs.iNumVerts;
	iNumIndex = rhs.iNumIndex;
	mtrl = rhs.mtrl;
	pGeomMesh = rhs.pGeomMesh;
	pVerts = new CUSTOMVERTEX[iNumIndex];
	iIndicies = new short[iNumVerts];
	for(int i=0; i < iNumVerts; i++)
	{
		pVerts[i] = rhs.pVerts[i];
		iIndicies[i] = rhs.iIndicies[i];
	}
}
ArbGeomNode& ArbGeomNode::operator=(const ArbGeomNode& rhs)
{
	iNumVerts = rhs.iNumVerts;
	iNumIndex = rhs.iNumIndex;
	mtrl = rhs.mtrl;
	pGeomMesh = rhs.pGeomMesh;
	pVerts = new CUSTOMVERTEX[iNumVerts];
	iIndicies = new short[iNumIndex];
	for(int i=0; i < iNumVerts; i++)
	{
		pVerts[i]= rhs.pVerts[i];
		iIndicies[i] = rhs.iIndicies[i];
	}
	return *this;
}
ArbGeomNode::~ArbGeomNode(void)
{
}

void ArbGeomNode::Build()
{
	if(pGeomMesh == NULL)
	{
		D3DXCreateMeshFVF(iNumIndex/3, iNumVerts, NULL, D3DFVF_CUSTOMVERTEX, pd3dDevice, &pGeomMesh);
		VOID* p_Vertices;
		if (FAILED(pGeomMesh->LockVertexBuffer(0, (void**)&p_Vertices)))
		{
			printf("BAD \n");
		}
		else
		{
			memcpy(p_Vertices, pVerts, iNumVerts*sizeof(CUSTOMVERTEX));
			pGeomMesh->UnlockVertexBuffer();
		}
		VOID* p_Indices;
		if (FAILED(pGeomMesh->LockIndexBuffer(0, (void**)&p_Indices)))
		{
			printf("BAD \n");
		}
		else
		{
			memcpy(p_Indices, iIndicies, iNumIndex*sizeof(short));
			pGeomMesh->UnlockIndexBuffer();
		}
		pGeomMesh->CloneMesh(0, NULL, pd3dDevice, &pGeomMesh);
		adjacency = new DWORD[iNumIndex];
		pGeomMesh->GenerateAdjacency(0.01f, adjacency);
		//D3DXCleanMesh(D3DXCLEAN_BACKFACING,pGeomMesh,adjacency,&pGeomMesh,adjacency,NULL);
		D3DXComputeTangentFrame(pGeomMesh,D3DXTANGENT_CALCULATE_NORMALS);
	}
}

void ArbGeomNode::SetNorms()
{
	for (int i = 0; i < iNumIndex / 3; i++)
	{
		D3DXVECTOR3 firstvec = pVerts[iIndicies[i*3+1]].position-pVerts[iIndicies[i*3]].position;
		D3DXVECTOR3 secondvec = pVerts[iIndicies[i*3]].position-pVerts[iIndicies[i*3+2]].position;
		D3DXVECTOR3 normal;
		D3DXVec3Cross(&normal, &firstvec, &secondvec);
		D3DXVec3Normalize(&normal,&normal);
		pVerts[iIndicies[i * 3]].normal += normal;
		pVerts[iIndicies[i * 3 + 1]].normal += normal;
		pVerts[iIndicies[i * 3 + 2]].normal += normal;
	}
	for (int i = 0; i < iNumVerts; i++)
		D3DXVec3Normalize(&(pVerts[i].normal),&(pVerts[i].normal));
}